'---------------------------------------------------------------------
'THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
'KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
'IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
'PARTICULAR PURPOSE.
'---------------------------------------------------------------------
Imports System
Imports System.Collections
Imports System.Collections.Generic
Imports System.Collections.Specialized
Imports System.ComponentModel
Imports System.Drawing.Design
Imports System.Security.Permissions
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.Util

Namespace Microsoft.Samples.Alert
    
    ''' <summary>
    ''' Represents a Button control which asks for confirmation when clicked.
    ''' </summary>
    <ToolboxData("<{0}:ConfirmButton runat=\""server\""></{0}:ConfirmButton>")> _
    Public Class ConfirmButton
        Inherits Button

        ' Using a dictionary of Alerts that we store in the context to avoid creating duplicate
        ' copies of the same Alert. This key is the key of the Page.Items object.
        Private Shared ContextAlertDictionaryKey As String = (GetType(ConfirmButton).AssemblyQualifiedName & "_AlertDictionary")

        ''' <summary>
        ''' Specify the ID of an Alert control to precisely control the layout of the confirm Alert.
        ''' </summary>
        <Category("Behavior"), _
         Themeable(False), _
         DefaultValue(""), _
         Description("Specify the ID of an Alert control to precisely control the layout of the confirm Alert."), _
         IDReferenceProperty(), _
         TypeConverter(GetType(ValidatedControlConverter))> _
        Public Property Alert() As String
            Get
                Dim s As String = CType(ViewState("Alert"), String)
                If (s Is Nothing) Then
                    Return String.Empty
                Else
                    Return s
                End If
            End Get
            Set(ByVal value As String)
                ViewState("Alert") = value
            End Set
        End Property

        ''' <summary>
        ''' If set to false, the button will behave like an ordinary button and won't show a confirm Alert.
        ''' </summary>
        <Category("Behavior"), _
         DefaultValue(True), _
         Description("If set to false, the button will behave like an ordinary button and won't show a confirm Alert.")> _
        Public Property Confirm() As Boolean
            Get
                Dim b As Object = ViewState("Confirm")
                If (b Is Nothing) Then
                    Return True
                Else
                    Return CType(b, Boolean)
                End If
            End Get
            Set(ByVal value As Boolean)
                ViewState("Confirm") = value
            End Set
        End Property

        ''' <summary>
        ''' The text that appears in the confirmation Alert (if the Alert property is empty).
        ''' </summary>
        <Category("Appearance"), _
         DefaultValue(""), _
         Description("The text that appears in the confirmation Alert (if the Alert property is empty).")> _
        Public Property ConfirmText() As String
            Get
                Dim s As String = CType(ViewState("ConfirmText"), String)
                If (s = Nothing) Then
                    Return String.Empty
                Else
                    Return s
                End If
            End Get
            Set(ByVal value As String)
                ViewState("ConfirmText") = value
            End Set
        End Property

        Public Overrides Property OnClientClick() As String
            Get
                Return MyBase.OnClientClick
            End Get
            Set(ByVal value As String)
                Throw New NotSupportedException("Setting OnClientClick is not supported on ConfirmButton.")
            End Set
        End Property

        Public Overrides Sub RenderControl(ByVal writer As HtmlTextWriter)
            If (DesignMode = False) Then
                If Confirm Then
                    Dim msg As Alert = Nothing
                    ' Was an Alert specified explicitly?
                    If (Alert.Length > 0) Then
                        ' Looking for the Alert in all naming containers.
                        Dim parent As Control = NamingContainer

                        Do While ((Not parent Is Nothing) AndAlso (msg Is Nothing))
                            msg = CType(parent.FindControl(Alert), Alert)
                            parent = parent.NamingContainer

                        Loop
                        If (msg Is Nothing) Then
                            Throw New HttpException(String.Format("Control {0} not found.", Alert))
                        End If
                    Else
                        ' Is there an Alert with the same message in the context?
                        Dim alertDictionary As Dictionary(Of String, Alert) = _
                            (CType(Page.Items(ContextAlertDictionaryKey), Dictionary(Of String, Alert)))
                        If (alertDictionary Is Nothing) Then
                            ' The dictionary has not yet been created.
                            alertDictionary = New Dictionary(Of String, Alert)()
                            Page.Items.Add(ContextAlertDictionaryKey, alertDictionary)
                        End If
                        If alertDictionary.ContainsKey(ConfirmText) Then
                            ' Fetching the cached Alert
                            msg = alertDictionary(ConfirmText)
                        Else
                            ' Alert not found in the page cache, creating and caching it.
                            msg = New Alert
                            msg.ID = (UniqueID & "_confirm")
                            msg.Page = Page
                            msg.EnableViewState = False
                            msg.Buttons = AlertButtons.YesNo
                            msg.HorizontalAlign = HorizontalAlign.Center
                            msg.Width = Unit.Pixel(300)
                            msg.Height = Unit.Pixel(80)
                            Dim LiteralText As LiteralControl = New LiteralControl
                            LiteralText.EnableViewState = False
                            LiteralText.Text = ConfirmText
                            msg.Controls.Add(LiteralText)
                            ' Store in the page cache
                            alertDictionary(ConfirmText) = msg
                            ' Render the Alert
                            msg.RenderControl(writer)
                        End If
                    End If
                    MyBase.OnClientClick = "return (" & msg.GetShowClientEvent & " == true)"
                Else
                    MyBase.OnClientClick = ""
                End If
            End If
            MyBase.RenderControl(writer)
        End Sub
    End Class
End Namespace
